<!-- public/viewer.html (修正版：防 InvalidStateError) -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Remote Browser Control</title>
  <style>
    body { 
      margin: 0; 
      background: #000; 
      display: flex; 
      justify-content: center; 
      align-items: center;
      height: 100vh;
      font-family: sans-serif;
    }
    #screen { 
      max-width: 90vw; 
      max-height: 90vh; 
      cursor: crosshair;
      border: 2px solid #444;
      box-shadow: 0 0 20px rgba(255,255,255,0.1);
    }
    #status { 
      position: fixed; 
      top: 10px; 
      left: 10px; 
      color: white; 
      font-size: 14px; 
      padding: 8px 12px;
      background: rgba(0,0,0,0.7);
      border-radius: 4px;
      backdrop-filter: blur(5px);
    }
    #screen:focus { outline: 2px solid #0af; }
  </style>
</head>
<body>
  <div id="status">Connecting to server...</div>
  <canvas id="screen" width="390" height="664" tabindex="1"></canvas>

  <script>
    const canvas = document.getElementById('screen');
    const ctx = canvas.getContext('2d');
    const statusEl = document.getElementById('status');
    
    // 👉 1. 解析 sessionId
    const urlParams = new URLSearchParams(window.location.search);
    const sessionId = urlParams.get('sessionId');
    
    if (!sessionId) {
      statusEl.textContent = "❌ Missing sessionId";
      statusEl.style.color = "red";
      throw new Error("No sessionId provided in URL");
    }

    // 👉 2. 创建 WebSocket 连接
    const ws = new WebSocket(`ws://localhost:3000/ws/${sessionId}`);
    ws.binaryType = 'arraybuffer';

    // 👉 3. 消息队列：存储连接建立前的操作
    const messageQueue = [];
    let isWsReady = false;

    // 👉 4. 发送消息的函数（带状态检查和队列）
    function sendMessage(data) {
      const message = JSON.stringify(data);
      
      if (isWsReady && ws.readyState === WebSocket.OPEN) {
        try {
          ws.send(message);
        } catch (e) {
          console.warn('Failed to send message:', e);
        }
      } else {
        // 排队，等待连接
        messageQueue.push(message);
        console.log('Queued message:', data);
      }
    }

    // 👉 5. 发送队列中的消息
    function flushQueue() {
      if (messageQueue.length > 0) {
        console.log(`Flushing ${messageQueue.length} queued messages`);
        messageQueue.forEach(msg => {
          try {
            ws.send(msg);
          } catch (e) {
            console.warn('Failed to send queued message:', e);
          }
        });
        messageQueue.length = 0; // 清空队列
      }
    }

    // 👉 6. WebSocket 事件监听

    ws.onopen = () => {
      console.log('WebSocket connection opened');
      isWsReady = true;
      statusEl.textContent = "🟢 Connected - Click to control";
      statusEl.style.color = "lightgreen";
      // 连接建立后，立即发送队列中的消息
      flushQueue();
    };

    ws.onmessage = (event) => {
      if (typeof event.data === 'string') {
        // 可能是服务器返回的响应或错误
        console.log('Server message:', event.data);
        return;
      }

      // 处理二进制数据（截图）
      const arrayBuffer = event.data;
      const blob = new Blob([arrayBuffer], { type: 'image/jpeg' });
      const url = URL.createObjectURL(blob);
      
      const img = new Image();
      img.onload = () => {
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        URL.revokeObjectURL(url);
      };
      img.onerror = () => {
        console.error('Failed to load image');
        URL.revokeObjectURL(url);
      };
      img.src = url;
    };

    ws.onclose = () => {
      console.log('WebSocket connection closed');
      isWsReady = false;
      statusEl.textContent = "🔴 Disconnected";
      statusEl.style.color = "red";
    };

    ws.onerror = (err) => {
      console.error('WebSocket error:', err);
      statusEl.textContent = "❌ Connection Error";
      statusEl.style.color = "red";
    };

    // 👉 7. 用户交互事件（使用 sendMessage 包装）

    // 鼠标点击
    canvas.addEventListener('click', (e) => {
      const rect = canvas.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;
      sendMessage({
        type: 'mouse',
        action: 'click',
        x, y
      });
    });

    // 鼠标移动（可选，频繁事件可节流）
    let lastMoveTime = 0;
    canvas.addEventListener('mousemove', (e) => {
      const now = Date.now();
      // 节流：避免发送过多移动事件
      if (now - lastMoveTime < 100) return; 
      lastMoveTime = now;

      const rect = canvas.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;
      sendMessage({
        type: 'mouse',
        action: 'move',
        x, y
      });
    });

    // 滚轮
    canvas.addEventListener('wheel', (e) => {
      e.preventDefault();
      sendMessage({
        type: 'wheel',
        deltaX: e.deltaX,
        deltaY: e.deltaY
      });
    });

    // 键盘事件
    canvas.addEventListener('keydown', (e) => {
      // 阻止默认行为（如页面滚动）
      if (['ArrowUp','ArrowDown','ArrowLeft','ArrowRight',' '].includes(e.key)) {
        e.preventDefault();
      }

      // 避免重复发送（可按需放开）
      if (e.repeat) return;

      sendMessage({
        type: 'key',
        key: e.key,
        code: e.code,
        ctrlKey: e.ctrlKey,
        shiftKey: e.shiftKey,
        altKey: e.altKey,
        metaKey: e.metaKey
      });
    });

    // 👉 8. 聚焦提示
    canvas.addEventListener('focus', () => {
      statusEl.textContent = "🟢 Connected - Focused! Use mouse/keyboard";
    });
    canvas.addEventListener('blur', () => {
      statusEl.textContent = "🟢 Connected - Click canvas to focus";
    });
  </script>
</body>
</html>